/*****************************************************************************************************/
/******************************		PROCESO FILESYSTEM		*****************************************/
/***************************************************************************************************/
#define FUSE_USE_VERSION 26
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
#include <stdint.h>
#include <fuse.h>
#include "operFuse.h"
#include "ConfSock.h"
#include <pthread.h>
#include <signal.h>
#include <semaphore.h>


int32_t cantConex;
int flagTerminado=1;
sem_t SemConsola;
sem_t semaforo;
 t_fs *FS; // ESTRUCTURA CON LA INFORMACION DEL FILESYSTEM
int32_t tamCache;
int32_t tamCacheG;
t_log *log;
int32_t logActivado;

pthread_mutex_t mutex_cache;
void cache_dump();

static struct fuse_operations OperPFS = {
	.getattr    = (void*)fuse_getattr,
	.readdir    = (void*)fuse_readdir,
	.open       = (void*)fuse_open,
	.read       = (void*)fuse_read,
	.truncate   = (void*)fuse_truncate,
	.create     = (void*)fuse_create,
	.release    = (void*)fuse_release,
	.write      = (void*)fuse_write,
	.unlink		= (void*)fuse_unlink,
	.flush    	= (void*)fuse_flush,

//funciones a crear

//mkdir /** Create a directory */
//rmdir /** Remove a directory */
//rename /** Rename a file */


};
t_pool VectorPool[10];
int32_t main(int32_t argc, char *argv[]){


	pthread_mutex_init(&mutex_cache, NULL);
	int32_t i=0;

	void *consola();
	cantConex= CantMaxConex();
	sem_init(&semaforo,10,cantConex);
	sem_init(&SemConsola,0,0);

	//VectorPool =(t_pool*) calloc(1,sizeof(t_pool)*(cantConex));
	void *FunFuse(void);
	pthread_t consolaID;
	int32_t fuse;

	tamCacheG = TamanioCacheG();
	tamCache = TamanioCache();
	logActivado = LogActivado();

	if (logActivado)
		log = log_create("PFS","log.txt",DEBUG|INFO|WARNING,M_CONSOLE_DISABLE);

	printf("---------------------------------------------------------------------------\n");
	printf("--------             Bienvenido al Proceso FileSystem              --------\n");
	printf("---------------------------------------------------------------------------\n\n\n");

	////Señal////
	signal(SIGUSR1, cache_dump);


	for(i=0;i<cantConex;i++){
		VectorPool[i].Sock=ConectarCapaAlmacenemiento();
		VectorPool[i].uso=0;
	}
	printf("-- Pool cargado con %d conexiones -- \n",cantConex );

	sem_wait(&semaforo);
	i=0;
	while(VectorPool[i].uso == 1){
		i++;
	}
	VectorPool[i].uso = 1;

	FS=cargar_fs(VectorPool[i].Sock);

	VectorPool[i].uso= 0;
	sem_post(&semaforo);


	if(pthread_create(&consolaID, NULL, (void *)consola ,NULL) != 0) {
		perror("Error al crear CONSOLA'S THREAD");
		return -1;
	}
	fuse = fuse_main(argc, argv, &OperPFS, NULL);


	sem_wait(&SemConsola);


	return 1;

}


void *consola(){
	extern t_fs *FS;
	char msjConsola[100],comandoConsola[100],path[50];
	int i=0,j=0;
	extern int flagTerminado;

	while(flagTerminado){
		i=0;
		j=0;
		memset(path,'\0',50);
		memset(msjConsola,'\0',100);
		memset(comandoConsola,'\0',100);

		puts("-Ingrese el comando:\n");
		fgets(msjConsola, 100, stdin);
		msjConsola[strlen(msjConsola)-1]='\0';

		while((msjConsola[i]!=' ')&&(msjConsola[i]!='\0')){
			comandoConsola[i] = msjConsola[i];
			i++;
		}
		i++;
		while((msjConsola[i]!=' ')&&(msjConsola[i]!='\0')){
			path[j] = msjConsola[i];
			i++;
			j++;
		}


		if(!strcmp(comandoConsola,"fsinfo")){
			printf("#Cantidad clusters ocupados:%d\n",FS->cantEntradasEnFAT-cantClustersLibres(FS) - 2);
			printf("#Cantidad de clusters libres:%d\n",cantClustersLibres(FS));
			printf("#Tamanio de un sector:%d bytes\n",FS->bootsector.bytesPorSector);
			printf("#Tamanio de un cluster:%d bytes\n",FS->tamCluster);
			printf("#Tamanio de la FAT:%d kb \n",FS->tamFatBytes/1024);
		}

		if(!strcmp(comandoConsola,"finfo")){

			puts("#Clusters:\n");

			Tentrada *dirElemento = NULL;
			t_elemento *elemento = obtener_elem(FS,path,&dirElemento);
			if (elemento == NULL){
				printf("Path erroneo \n");
			}
			else{
				int32_t cluster = elemento->primerCluster;
				printf("%d ",NUM_CLUSTER(cluster));

				while (!ESFAT_EOC(FS->tablaFAT[cluster])) {
					cluster = FS->tablaFAT[cluster];
					printf("%d ",NUM_CLUSTER(cluster));
				}
			}
			printf("\n");
		}

		if(!strcmp(msjConsola,"clear")){
			system("clear");
		}
		if(!strcmp(msjConsola,"exit")){
			sem_post(&SemConsola);
			exit(EXIT_SUCCESS);
			flagTerminado=0;
		}

		if((strcmp(comandoConsola,"fsinfo"))&&(strcmp(comandoConsola,"finfo"))&&(strcmp(comandoConsola,"clear")) && (strcmp(comandoConsola,"exit"))){
			printf("Mensaje incorrecto.\n");
		}
	}

}


void cache_dump(){

	Tentrada *raiz = FS->rootDirectoryContent;

	cache_dump1(raiz);
}









